```vue
<template>
    <div class="home-container">
        <!-- 粒子背景容器 -->
        <div class="particles-bg"></div>
        <header class="header">
            <div class="user-info">
                <div class="avatar-container">
                    <div class="avatar-wrapper">
                        <img v-if="!userLoading" :src="user.headPicture" alt="用户头像" class="avatar" @click="toggleAvatar"
                            @error="handleAvatarError" />
                        <div v-else class="avatar-skeleton"></div>
                    </div>
                    <span class="username">{{ user.name }}</span>
                </div>
                <div class="date-info">
                    {{ currentDate }}
                </div>
            </div>
        </header>

        <main class="main-content">
            <div class="overview-cards">
                <div class="card" v-for="item in overviewData" :key="item.title"
                    :style="{ '--card-color': item.color }">
                    <div class="card-icon">
                        <i :class="item.icon"></i>
                    </div>
                    <div class="card-content">
                        <h3>{{ item.title }}</h3>
                        <p>{{ item.value }}</p>
                    </div>
                </div>
            </div>

            <div class="chart-container">
                <!-- 商品排行榜 -->
                <div class="chart-card">
                    <h3>商品前十排行榜</h3>
                    <div class="chart-wrapper">
                        <el-skeleton v-if="goodsChartLoading" :rows="10" animated style="height: 420px;" />
                        <v-chart v-else class="chart" :option="goodsChartOption" :autoresize="true"
                            ref="goodsChartRef" />
                    </div>
                </div>

                <!-- 活跃度分析 -->
                <div class="chart-card">
                    <h3>活跃度分析</h3>
                    <div class="chart-header">
                        <div class="chart-controls">
                            <el-select v-model="timeRangeType" placeholder="选择时间范围" size="small"
                                @change="handleTimeRangeChange" style="width: 120px; margin-right: 10px;">
                                <el-option label="按周" value="WEEK"></el-option>
                                <el-option label="按月" value="MONTH"></el-option>
                                <el-option label="按年" value="YEAR"></el-option>
                            </el-select>
                            <div class="time-controls">
                                <el-button size="small" @click="prevPeriod" :disabled="isFirstPeriod"
                                    icon="el-icon-arrow-left">
                                    上一{{ timeRangeText }}
                                </el-button>
                                <span class="time-range">{{ currentTimeRange }}</span>
                                <el-button size="small" @click="nextPeriod" :disabled="isCurrentPeriod"
                                    icon="el-icon-arrow-right">
                                    下一{{ timeRangeText }}
                                </el-button>
                            </div>
                        </div>
                    </div>
                    <div class="chart-wrapper">
                        <el-skeleton v-if="activityChartLoading" :rows="10" animated style="height: 420px;" />
                        <v-chart v-else class="chart" :option="activityChartOption" :autoresize="true"
                            ref="activityChartRef" />
                    </div>
                </div>
            </div>
        </main>
    </div>
</template>

<script>
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, BarChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from 'echarts/components'
import VChart from 'vue-echarts'
import { getUser, getUserById } from '@/api/admin/User'
import { getActiveUserNumberByWeek, getGoodsTop10 } from '@/api/admin/active'
import {
    format, startOfWeek, endOfWeek, isSameWeek, startOfMonth, endOfMonth, isSameMonth,
    subMonths, addMonths, startOfYear, endOfYear, isSameYear, subYears, addYears,
    subWeeks, addWeeks, getDaysInMonth
} from 'date-fns'

use([CanvasRenderer, LineChart, BarChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent])

export default {
    name: 'HomePage',
    components: { VChart },
    data() {
        return {
            user: {
                name: '加载中...',
                headPicture: '/default-avatar.png'
            },
            userLoading: true,
            goodsChartLoading: true,
            goodsChartOption: {
                tooltip: { trigger: 'axis', formatter: '{b} : {c} 次', axisPointer: { type: 'shadow' } },
                grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
                xAxis: { type: 'value', name: '访问量', nameTextStyle: { color: '#64748b' } },
                yAxis: { type: 'category', data: [], axisLabel: { width: 120, overflow: 'truncate' }, inverse: true },
                series: [{ name: '访问量', type: 'bar', data: [], itemStyle: { color: '#409EFF' }, label: { show: true, position: 'right' } }]
            },
            activityChartLoading: true,
            timeRangeType: 'WEEK',
            currentPage: 0,
            currentDateRange: startOfWeek(new Date()),
            activityChartOption: {
                tooltip: { trigger: 'axis' },
                legend: { data: ['活跃用户'], textStyle: { color: '#64748b' } },
                grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
                xAxis: { type: 'category', boundaryGap: false, data: [], axisLabel: { color: '#64748b' } },
                yAxis: { type: 'value', axisLabel: { color: '#64748b' } },
                series: [{
                    name: '活跃用户', type: 'line', data: [], smooth: true, itemStyle: { color: '#67C23A' },
                    areaStyle: {
                        color: {
                            type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [
                                { offset: 0, color: 'rgba(103, 194, 58, 0.5)' },
                                { offset: 1, color: 'rgba(103, 194, 58, 0.1)' }
                            ]
                        }
                    }
                }]
            },
            currentDate: this.formatDate(new Date()),
            overviewData: [
                { title: '总访问量', value: '12,345', icon: 'el-icon-user', color: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)' },
                { title: '新增用户', value: '1,234', icon: 'el-icon-user-solid', color: 'linear-gradient(135deg, #10b981 0%, #059669 100%)' },
                { title: '订单数量', value: '567', icon: 'el-icon-shopping-cart-2', color: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)' },
                { title: '总收入', value: '¥45,678', icon: 'el-icon-money', color: 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)' }
            ]
        }
    },
    computed: {
        currentTimeRange() {
            switch (this.timeRangeType) {
                case 'WEEK': return `${format(this.currentDateRange, 'yyyy-MM-dd')} 至 ${format(endOfWeek(this.currentDateRange), 'yyyy-MM-dd')}`
                case 'MONTH': return format(this.currentDateRange, 'yyyy年MM月')
                case 'YEAR': return format(this.currentDateRange, 'yyyy年')
                default: return ''
            }
        },
        isCurrentPeriod() {
            const now = new Date()
            switch (this.timeRangeType) {
                case 'WEEK': return isSameWeek(this.currentDateRange, now)
                case 'MONTH': return isSameMonth(this.currentDateRange, now)
                case 'YEAR': return isSameYear(this.currentDateRange, now)
                default: return false
            }
        },
        isFirstPeriod() { return this.currentPage >= 12 },
        timeRangeText() { return { WEEK: '周', MONTH: '月', YEAR: '年' }[this.timeRangeType] || '' }
    },
    methods: {
        formatDate(date) {
            const year = date.getFullYear()
            const month = String(date.getMonth() + 1).padStart(2, '0')
            const day = String(date.getDate()).padStart(2, '0')
            const weekdays = ['日', '一', '二', '三', '四', '五', '六']
            const weekday = weekdays[date.getDay()]
            return `${year}年${month}月${day}日 星期${weekday}`
        },
        toggleAvatar() {
            this.$message.success('点击了头像！')
        },
        handleAvatarError(e) {
            this.user.headPicture = '/default-avatar.png' // 直接设置默认头像
            this.userLoading = false // 同步更新加载状态
        },
        async loadGoodsData() {
            this.goodsChartLoading = true
            try {
                const response = await getGoodsTop10()
                if (response.data.code === 1) {
                    this.updateGoodsChartData(response.data.data)
                }
            } catch (error) {
                console.error('获取商品排行榜数据失败:', error)
                this.$message.error('获取商品数据失败')
            } finally {
                this.goodsChartLoading = false
            }
        },
        updateGoodsChartData(data) {
            this.goodsChartOption.yAxis.data = data.map(item => item.goodsId)
            this.goodsChartOption.series[0].data = data.map(item => item.userId)
            this.$nextTick(() => {
                if (this.$refs.goodsChartRef) this.$refs.goodsChartRef.resize()
            })
        },
        async loadActivityData() {
            this.activityChartLoading = true
            try {
                const response = await getActiveUserNumberByWeek(this.timeRangeType, this.currentPage)
                if (response.data.code === 1) {
                    this.updateActivityChartData(response.data.data)
                }
            } catch (error) {
                console.error('获取活跃度数据失败:', error)
                this.$message.error('获取活跃度数据失败')
            } finally {
                this.activityChartLoading = false
            }
        },
        updateActivityChartData(data) {
            const xAxisData = {
                WEEK: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
                MONTH: Array.from({ length: getDaysInMonth(this.currentDateRange) }, (_, i) => `${i + 1}日`),
                YEAR: Array.from({ length: 12 }, (_, i) => `${i + 1}月`)
            }[this.timeRangeType]

            this.activityChartOption.xAxis.data = xAxisData
            this.activityChartOption.series[0].data = data
            this.$nextTick(() => {
                if (this.$refs.activityChartRef) this.$refs.activityChartRef.resize()
            })
        },
        handleTimeRangeChange() {
            this.currentPage = 0
            this.resetDateRange()
            this.loadActivityData()
        },
        resetDateRange() {
            const now = new Date()
            this.currentDateRange = { WEEK: startOfWeek, MONTH: startOfMonth, YEAR: startOfYear }[this.timeRangeType](now)
        },
        prevPeriod() {
            if (!this.isFirstPeriod) {
                this.currentPage++
                this.adjustDateRange(-1)
                this.loadActivityData()
            }
        },
        nextPeriod() {
            if (!this.isCurrentPeriod) {
                this.currentPage--
                this.adjustDateRange(1)
                this.loadActivityData()
            }
        },
        adjustDateRange(amount) {
            this.currentDateRange = {
                WEEK: amount > 0 ? addWeeks : subWeeks,
                MONTH: amount > 0 ? addMonths : subMonths,
                YEAR: amount > 0 ? addYears : subYears
            }[this.timeRangeType](this.currentDateRange, Math.abs(amount))
        }, formatImagePath(path) {
            if (!path) return this.defaultAvatar;

            console.log('原始路径:', path);
            // 清理路径中的引号和前后空格
            let cleanPath = path.replace(/["']/g, '').trim();
            console.log('清理后路径:', cleanPath);

            // 匹配所有系统路径（Windows: C:\a\b.png，Linux: /home/a/b.png），提取最后一个 / 或 \ 后的文件名
            const fileNameMatch = cleanPath.match(/([^\\/]+)\.(\w+)$/);
            if (fileNameMatch && fileNameMatch[1] && fileNameMatch[2]) {
                const fileName = `${fileNameMatch[1]}.${fileNameMatch[2]}`;
                console.log('提取的文件名:', fileName);
                const imageUrl = `http://localhost:8090/images/${fileName}`;
                console.log('生成的图片URL:', imageUrl);
                return imageUrl;
            }

            return cleanPath || this.defaultAvatar;
        },

        async loadUserData() {
            this.userLoading = true
            try {
                const user = JSON.parse(getUser())
                const response = await getUserById(user.id)
                const userData = response.data.data

                console.log('=== 加载用户信息 ===')
                console.log('数据库中的头像路径:', userData.headPicture)

                // 处理头像路径
                const processedHeadPicture = this.formatImagePath(userData.headPicture)
                this.user = {
                    name: userData.name,
                    headPicture: processedHeadPicture
                }
            } catch (error) {
                console.error('获取用户数据失败:', error)
                this.user = {
                    name: '未知用户',
                    headPicture: '/default-avatar.png'
                }
            } finally {
                this.userLoading = false
            }
        },
        resizeCharts() {
            if (this.$refs.goodsChartRef) this.$refs.goodsChartRef.resize()
            if (this.$refs.activityChartRef) this.$refs.activityChartRef.resize()
        },
        handleResize() {
            this.resizeCharts()
        }
    },
    async mounted() {
        await Promise.all([
            this.loadUserData(),
            this.loadGoodsData(),
            this.loadActivityData()
        ])
        window.addEventListener('resize', this.handleResize)
    },
    beforeDestroy() {
        window.removeEventListener('resize', this.handleResize)
    }
}
</script>

<style scoped>
.home-container {
    position: relative;
    min-height: 100vh;
    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    padding: 20px;
}

.particles-bg {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
}

.header {
    position: relative;
    z-index: 1;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    padding: 20px;
    margin-bottom: 24px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.user-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.avatar-container {
    display: flex;
    align-items: center;
    gap: 16px;
}

.avatar-wrapper {
    position: relative;
    width: 60px;
    height: 60px;
}

.avatar {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    cursor: pointer;
    transition: transform 0.3s ease;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.avatar:hover {
    transform: scale(1.05);
}

.avatar-skeleton {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: loading 1.5s infinite;
}

@keyframes loading {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

.username {
    font-size: 18px;
    font-weight: 600;
    color: #2d3748;
}

.date-info {
    font-size: 16px;
    color: #64748b;
    font-weight: 500;
}

.main-content {
    position: relative;
    z-index: 1;
}

.overview-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
    margin-bottom: 24px;
}

.card {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    padding: 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.card-icon {
    width: 56px;
    height: 56px;
    border-radius: 12px;
    background: var(--card-color);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 24px;
}

.card-content h3 {
    margin: 0 0 8px 0;
    font-size: 14px;
    font-weight: 500;
    color: #64748b;
}

.card-content p {
    margin: 0;
    font-size: 24px;
    font-weight: 700;
    color: #2d3748;
}

.chart-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}

.chart-card {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border-radius: 16px;
    padding: 24px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.chart-card h3 {
    margin: 0 0 20px 0;
    font-size: 18px;
    font-weight: 600;
    color: #2d3748;
}

.chart-header {
    margin-bottom: 20px;
}

.chart-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}

.time-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.time-range {
    font-size: 14px;
    color: #64748b;
    font-weight: 500;
    min-width: 200px;
    text-align: center;
}

.chart-wrapper {
    height: 420px;
}

.chart {
    width: 100%;
    height: 100%;
}

@media (max-width: 1024px) {
    .chart-container {
        grid-template-columns: 1fr;
    }

    .overview-cards {
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    }
}

@media (max-width: 640px) {
    .home-container {
        padding: 12px;
    }

    .header {
        padding: 16px;
    }

    .user-info {
        flex-direction: column;
        gap: 12px;
        text-align: center;
    }

    .overview-cards {
        grid-template-columns: 1fr;
    }

    .card {
        padding: 20px;
    }

    .chart-controls {
        flex-direction: column;
        align-items: stretch;
    }

    .time-controls {
        justify-content: center;
    }
}
</style>